﻿using Enter.Enums;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
// 枚举 https://github.com/TylerBrinkley/Enums.NET
namespace Enter.Utils.EnumExt
{
    public static class EnumExtend
    {

        public static ConcurrentDictionary<string, List<EnumSelectListItem>> EnumMap;
        static EnumExtend()
        {
            InitEnumMap();
        }

        public static void InitEnumMap()
        {
            EnumMap = new ConcurrentDictionary<string, List<EnumSelectListItem>>();
            var enums = Assembly.GetAssembly(typeof(EnumYesNo)).GetTypes().Where(t => t.Namespace == "Enter.Enums" && t.IsEnum);
            foreach (var item in enums)
            {
                EnumMap.TryAdd(item.Name, EnumList(item));
            }
        }

        public static List<EnumSelectListItem> EnumList(string enumName, bool insert = true)
        {
            return EnumMap.EnumList(enumName, insert);
        }

        public static List<EnumSelectListItem> EnumList(this ConcurrentDictionary<string, List<EnumSelectListItem>> enumMap, string enumName, bool insert = true)
        {
            var new_items = new List<EnumSelectListItem>();
            enumMap.TryGetValue(enumName, out var items);
            if (insert)
            {
                new_items.Add(new EnumSelectListItem { Value = "", Text = "请选择", Selected = true });
            }
            foreach (var item in items)
            {
                new_items.Add(item);
            }
            return new_items;
        }

        public static List<EnumSelectListItem> EnumList<T>(bool insert = true) where T : Enum
        {
            var enumType = typeof(T);
            return EnumList(enumType, insert);
        }

        public static List<EnumSelectListItem> EnumList(Type enumType, bool insert = true)
        {
            List<EnumSelectListItem> list = new List<EnumSelectListItem>();
            FieldInfo[] fields = enumType.GetFields();
            foreach (FieldInfo field in fields)
            {
                if (!field.FieldType.IsEnum)
                    continue;
                string value = ((int)field.GetValue(null)).ToString();
                {
                    var attr = field.GetCustomAttribute(typeof(ValueAttribute)) as ValueAttribute;
                    if (attr != null)
                    {
                        value = attr.Value;
                    }
                }
                string text = field.Name;
                {
                    // field.IsDefined(typeof(DisplayAttribute), true)
                    var attr = field.GetCustomAttribute(typeof(DisplayAttribute)) as DisplayAttribute;
                    if (attr != null)
                    {
                        text = attr.Name;
                    }
                }
                list.Add(new EnumSelectListItem { Value = value.ToString(), Text = text });//((int)e).ToString() 
            }
            if (insert)
            {
                var items = enumType.GetCustomAttributes<SelectListItemAttribute>();
                if (items != null)
                {
                    foreach (var item in items)
                    {
                        var order = item.Order;
                        if (item.Order < 0)
                        {
                            order = list.Count + 1 + item.Order;
                        }
                        list.Insert(order, new EnumSelectListItem { Value = item.Value, Text = item.Text, Selected = item.Selected });
                    }
                }
            }
            return list;
        }
    }
}
